import type { PageType } from '../../../lib/page_handler/type'
import type {
  ComponentStyleIdType,
  PlatformTypeValue,
} from '../../../types/interfaces'
import { BaseModule } from '../../../lib/abstract'
import { PageHandler } from '../../../lib/page_handler'
import { GreasyForkPageType } from '../../../lib/page_handler/platform/greasyfork/types'
import { ToolKit } from '../../../lib/utils/toolkit'
import {
  BodyAttrs,
  ComponentStyleId,
  HOSTNAME,
  logger,
  SUPPORTED_PLATFORMS,
} from '../../../types/constants'
import { SYMBOLS } from '../../../types/interfaces'
import { ConfigManager } from '../../config_manager'

// 单个链接选择器配置
interface ILinkSelectorConfig {
  /**
   * 链接选择器
   */
  selector: string
  /**
   * 需要排除的容器选择器
   */
  excludeContainers?: string[]
}
// 页面链接配置
interface PageLinkSelectorConfig {
  [pageType: string]: ILinkSelectorConfig[]
}
// 平台链接配置
export type PlatformLinkSelectorConfig = Record<PlatformTypeValue, PageLinkSelectorConfig>

interface Config {
  enabled?: boolean
}

export class BeautifyLink extends BaseModule {
  readonly id: string = 'beautify_link'
  readonly styleId: string = ComponentStyleId[this.name]
  isInitialized: boolean = false
  readonly supportedPlatforms: string[] = ConfigManager.getInstance().moduleSupportedPlatforms(this.name)
  private static instance: BeautifyLink
  private currentPageType: PageType | null = null
  private readonly LinkConfig: PlatformLinkSelectorConfig = {}
  private readonly maxLinkLength: number = 40
  private readonly maxLinkTextLength: number = 20

  config: Config = {
    enabled: true,
  }

  get name(): ComponentStyleIdType {
    return 'BeautifyLink'
  }

  restoreOriginalState(): void {
    const $link = $('[data-beautified="true"]')
    const href = $link.attr('title') || ''

    $link
      .removeAttr('title')
      .removeAttr('data-beautified')
      .text(href)
  }

  constructor() {
    super()

    this.LinkConfig = {
      [SUPPORTED_PLATFORMS.GREASY_FORK]: {
        // 测试链接：
        // 1）https://greasyfork.org/zh-CN/scripts/533339/discussions/307876
        // 2）https://greasyfork.org/zh-CN/scripts/384538/discussions/268041
        [GreasyForkPageType.SCRIPT_DISCUSSION]: [
          {
            selector: '#script-content .user-content a',
            excludeContainers: ['.user-screenshots'],
          },
        ],
        // 测试链接：https://greasyfork.org/zh-CN/scripts/418605/discussions/308007
        [GreasyForkPageType.DISCUSSIONS_DETAIL]: [
          {
            selector: '.text-content .user-content a',
            excludeContainers: ['.user-screenshots'],
          },
        ],
      },
    }
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): BeautifyLink {
    if (!BeautifyLink.instance) {
      BeautifyLink.instance = new BeautifyLink()
    }
    return BeautifyLink.instance
  }

  core(): void {
    this.loadConfig()

    if (!this.config.enabled)
      return

    this.handleLink()
  }

  onToggleCallback(_id: string, checked: boolean): void {
    super.onToggleCallback(_id, checked)
  }

  handleLink(): void {
    this.currentPageType = PageHandler.getCurrentPageType()
    const configs = this.LinkConfig[HOSTNAME][this.currentPageType] || []

    if (!configs.length)
      return

    configs.forEach((config) => {
      const $links = this.getQualifiedLinks(config.selector, config.excludeContainers)

      if (!$links || $links.length === 0)
        return

      $links.each((_, element) => {
        const $link = $(element)
        const text = $link.text()
        const href = $link.attr('href') || ''
        const fullUrl = ToolKit.browser.url.getFullUrl(href)

        try {
          const url = new URL(fullUrl)

          if (text === href && text.length > this.maxLinkLength) {
            $link
              .attr('title', href)
              .attr(BodyAttrs.LINK_CONTENT, text)
              .attr('data-beautified', 'true')
              .text(`${SYMBOLS.STATUS.LINK}${this.generateDisplayText(url)}`)
          }
        }
        // eslint-disable-next-line unused-imports/no-unused-vars
        catch (e) {
          logger.warn(`[${this.name}] Invalid URL: ${href}`)
        }
      })
    })
  }

  /**
   * 获取符合条件的选择器（排除指定容器内的元素）
   */
  private getQualifiedLinks(selector: string, excludeSelectors?: string[]): JQuery {
    let $links = $(selector)

    if (excludeSelectors?.length) {
      excludeSelectors.forEach((exclude) => {
        $links = $links.not(`${exclude} a`)
      })
    }

    return $links
  }

  /**
   * 生成优化后的链接显示文本
   */
  private generateDisplayText(url: URL): string {
    const domain = url.hostname.replace('www.', '')
    const pathSegments = url.pathname.split('/').filter(Boolean)

    // 无路径情况
    if (pathSegments.length === 0) {
      return domain
    }

    // 取最后两个有效路径段
    const lastTwoSegments = pathSegments.slice(-2)

    return ToolKit.string.truncate(`/${lastTwoSegments.join('/')}`, this.maxLinkTextLength)
  }

  applyConfig(config: Partial<Config>): void {
    super.updateConfig(config)

    this.handleLink()

    logger.info(`[${this.name}] Config updated and apply`, this.config)
  }

  getStyles(): string {
    return `
`
  }
}
